//
//  STDSPath.hpp
//  STDSRenderSDKIOS
//
//  Created by 陈学明 on 2023/3/27.
//

#ifndef STDSPath_hpp
#define STDSPath_hpp

#include <stdio.h>
#include <glm/glm.hpp>
#include "STDSPathTypes.h"
#include <initializer_list>
#include <memory>
#include <vector>

using namespace glm;
using namespace std;

// 路径的单元
struct STDSPathUnit {
    STDSPathUnit(long idx, STDSPathVerb type, int count):mStartIndex(idx), mType(type), mCount(count) {}
    long mStartIndex; // 开始位置
    STDSPathVerb mType; // 类型
    int mCount{0};
};

class STDSPath {
    STDSPath() {
        
    }
    
    ~STDSPath() {
        
    }
    
public:
    void moveTo(float x, float y) {
        mMovePoint = vec2(x, y);
        mPoints.push_back(vec2(x, y));
    }
    
    void moveTo(const vec2& p) {
        mMovePoint = p;
        mPoints.push_back(p);
    }
    
    void lineTo(float x, float y) {
        mIdxs.push_back(STDSPathUnit(mPoints.size() - 1, STDSPathVerbLine, 2));
        mPoints.push_back(vec2(x, y));
    }
    
    void lineTo(const vec2& p) {
        mIdxs.push_back(STDSPathUnit(mPoints.size() - 1, STDSPathVerbLine, 2));
        mPoints.push_back(p);
    }
    
    void quadTo(float x1, float y1, float x2, float y2) {
        mIdxs.push_back(STDSPathUnit(mPoints.size() - 1, STDSPathVerbQuad, 3));
        mPoints.push_back(vec2(x1, y1));
        mPoints.push_back(vec2(x2, y2));
    }
    
    void quadTo(const vec2& p1, const vec2& p2) {
        mIdxs.push_back(STDSPathUnit(mPoints.size() - 1, STDSPathVerbQuad, 3));
        mPoints.push_back(p1);
        mPoints.push_back(p2);
    }
    
    void cubicTo(float x1, float y1, float x2, float y2, float x3, float y3) {
        mIdxs.push_back(STDSPathUnit(mPoints.size() - 1, STDSPathVerbCubic, 4));
        mPoints.push_back(vec2(x1, y1));
        mPoints.push_back(vec2(x2, y2));
        mPoints.push_back(vec2(x3, y3));
    }
    
    void cubicTo(const vec2& p1, const vec2& p2, const vec2& p3) {
        mIdxs.push_back(STDSPathUnit(mPoints.size() - 1, STDSPathVerbCubic, 4));
        mPoints.push_back(p1);
        mPoints.push_back(p2);
        mPoints.push_back(p3);
    }
    
    void close() {
        mIdxs.push_back(STDSPathUnit(mPoints.size() - 1, STDSPathVerbLine, 2));
        mPoints.push_back(mMovePoint);
    }
    
    long getVerbCount() {
        return mIdxs.size();
    }
    
    long getPointCount() {
        return mPoints.size();
    }
    
private:
    int countVerb{0};// 线的数量
    int countPoint{0};// 点的数量
    int mLastMoveToIndex; // 最后一个点移动到的位置
    vec2 lastPoint;// 最后一个点
    vec2 mMovePoint;
    vector<vec2> mPoints;// 顶点数组
    vector<STDSPathUnit> mIdxs;// 顶点索引
    STDSPathFillType mFillType;
};
#endif /* STDSPath_hpp */
